﻿using System;
using System.Net;
using System.Net.Mail;
using System.Threading;

namespace MailSender
{
    public class Sender
    {
        private Settings _settings;
        private readonly string[] _emails;
        private SmtpClient _smtp;
        private MailMessage _message;
        private bool _inProgress;
        private object _synh = new object();
        private bool _StopFlag = false;

        public Sender(Settings settings, string[] emails)
        {
            _settings = settings;
            _emails = emails;
        }

        public bool InProgress
        {
            get
            {
                lock (_synh)
                    return _inProgress;
            }
            set
            {
                lock (_synh)
                    _inProgress = value;
            }

        }


        public void Send(Action<string> writeLog, Action<int> progress, Action onEnd)
        {
            InitSmtp();
            var cnt = _emails.Length;
            int sended = 0;
            new Thread(() =>
                {
                    InProgress = true;

                    for (int i = 0; i < cnt; i++)
                        try
                        {
                            if (_StopFlag)
                            {
                                writeLog("Остановлено пользователем!");
                                break;
                            }

                            SendTo(email: _emails[i]);
                            progress((int)(((double)i) / ((double)cnt) * 100.0));
                            sended++;
                            if (i % _settings.SendInTime == 0)
                            {
                                writeLog("Отправлено " + i + " писем");
                                if (_settings.SendInterval >0)
                                Thread.Sleep(_settings.SendInterval * 1000);
                            }
                        }
                        catch (Exception ex)
                        {

                            writeLog("Ошибка при отправке письма " + _emails[i] + ex.Message);
                        }

                    progress(100);
                    writeLog("Отправлено " + (sended) + " писем из " + cnt);
                    InProgress = false;
                    onEnd();
                    _StopFlag = false;
                }).Start();
        }

        private void SendTo(string email)
        {
            _message.To.Clear();
            _message.To.Add(email);
            _smtp.Send(_message);
        }


        private void InitSmtp()
        {
            _smtp = new SmtpClient(_settings.Host, _settings.Port);
            _smtp.Credentials = new NetworkCredential { Password = _settings.Password, UserName = _settings.User };
            _smtp.EnableSsl = _settings.UseSsl;

            _message = new MailMessage(_settings.FromAddress, "eml@eml.ru");
            _message.Subject = _settings.Subject;
            _message.IsBodyHtml = _settings.BodyInHtml;
            _message.Body = _settings.Body;

            if (_settings.Attache != null && _settings.Attache.Count > 0)
            {
                _settings.Attache.ForEach(s => _message.Attachments.Add(new Attachment(s)));
            }

        }

        public void Stop()
        {
            StopSending();
        }

        private void StopSending()
        {
            if (InProgress)
                _StopFlag = true;
        }
    }
}